//
//  LevelScene.m
//  cocos2dt1
//
//  Created by mmac on 1/17/10.
//  Copyright 2010 __MyCompanyName__. All rights reserved.
//

#import "constant.h"

#import "LevelScene.h"
#import "FinishScene.h"

#import "LineLayer.h"
#import "TimerBarLayer.h"

#import "GameData.h"



block_position block_position_make(int i, int j){
    block_position p; 
	p.i = i;
	p.j = j;
	return p;
}


/*
 enum {
 kBlock0,
 kBlock1,
 kBlock2,
 kBlock3,
 kBlock4,
 kBlock5,
 kBlock6,
 kBlock7,
 kBlock8,
 kBlock9,
 } block_types ;
 */

@implementation LevelScene

+(id) scene
{
	// 'scene' is an autorelease object.
	Scene *scene = [Scene node];
	
	// 'layer' is an autorelease object.
	LevelScene *layer = [LevelScene node];
	
	// add layer as a child to scene
	[scene addChild: layer z:0 tag:kTagLevelLayer];
	// [layer setLevel:1];
	
	// return the scene
	return scene;
}

+(id) sceneLevel:(int)lvl
{
	// 'scene' is an autorelease object.
	Scene *scene = [Scene node];
	
	// 'layer' is an autorelease object.
	LevelScene *layer = [LevelScene node];
	// [layer setLevel:lvl];
	
	// add layer as a child to scene
	[scene addChild: layer z:0 tag:kTagLevelLayer];
	
	// return the scene
	return scene;
}

-(void) setLevel:(int)lvl
{
	// level = lvl;
	[[GameData sharedObject] setLevel:lvl];
}

// on "init" you need to initialize your instance
-(id) init
{
	// always call "super" init
	// Apple recommends to re-assign "self" with the "super" return value
	if( (self=[super init] )) {
		
		self.isTouchEnabled = YES;
		
		
		
		int level = [[GameData sharedObject] getLevel];
		
		if(level < 1){
			level = 1;
		}
		NSLog(@"start level: %d", level);
		
		
		block_left_number = BLOCK_ROW_NUMBER * BLOCK_COL_NUMBER;
		block_type_number = BLOCK_TYPE_INIT_NUMBER + level / 2;
		// block_type_number = 10 + level / 2;
		
		block_shift_direction = level % 5;
		
		// block_left_number = 8;
		
		// create and initialize a Label
		// Label* label = [Label labelWithString:@"Intro" fontName:@"Marker Felt" fontSize:64];
		
		// ask director the the window size
		CGSize size = [[Director sharedDirector] winSize];
		
		// position the label on the center of the screen
		// label.position =  ccp( size.width /2 , size.height/2 );
		
		// add the label as a child to this Layer
		// [self addChild: label];
		// ta = [[TextureAtlas alloc] initWithFile:@"blocks.png" capacity:16];
		// [ta drawQuads];
		
		// bg
		NSString *bgName = [[NSString alloc] initWithFormat:@"level_bg_%d.png", level];
		Sprite *sprite = [Sprite spriteWithFile:bgName];
		sprite.position = ccp( size.width / 2, size.height / 2);
		[self addChild:sprite z:0];
		
		
		// LineLayer
		LineLayer *ll = [[LineLayer alloc] init];
		[ll clearPath];
		[self addChild:ll z:5 tag:kLineLayer];
		
		// mask
		Sprite *sprite2 = [Sprite spriteWithFile:@"block_sel_mask.png"];
		sprite2.position = ccp( -100, -100);
		sprite2.visible = FALSE;
		[self addChild:sprite2 z:20 tag:kBlockSpriteMask];
		
		
		// create blocks
		AtlasSpriteManager *mgr = [AtlasSpriteManager spriteManagerWithFile:@"blocks.png" capacity:50];
		[self addChild:mgr z:10 tag:kTagSpriteManager];
		
		// CGSize s = [[Director sharedDirector] winSize];
		// [self addNewSpriteWithCoords:ccp(s.width/2, s.height/2)];
		
		[self initBlocks];
		
		[self drawBlocks];
		
		// init checked block
		selectedBlock.i = -1;
		selectedBlock.j = -1;
		
		// [self schedule: @selector(blockLineClear:) interval:0.5];
		
		
		// create and initialize a Label
		NSString *levelName = [[NSString alloc] initWithFormat:@"Level %d", level];
		Label* levelLabel = [Label labelWithString:levelName fontName:@"Marker Felt" fontSize:30];
		levelLabel.position =  CGPointMake( 90.0, 304.0 );
		[self addChild:levelLabel z:5 tag:kTagLevelNameLayer];
		NSLog(@"%@", levelName);
		
		
		// timer
		TimerBarLayer *tbl = [[TimerBarLayer alloc] init];
		[self addChild:tbl z:5 tag:kTagTimerBarLayer];
		
	}	
	return self;
}


// AtlasSpriteManager *mgr = (AtlasSpriteManager*) [self getChildByTag:kTagSpriteManager];


- (void)initBlocks{
	int i,j;
	int k = 0;
	int idx;
	
	
	for(j=0; j< BLOCK_COL_NUMBER; j++){	
		for(i=0; i< BLOCK_ROW_NUMBER; i=i+2){
			
			// get block
			//int idx = arc4random() % 10;
			idx = k % block_type_number;
			
			
			blocks[i][j] = idx;
			blocks[i+1][j] = idx;
			
			// NSLog(@"block: (%d,%d) %d", i,j,idx);
			// NSLog(@"block: (%d,%d) %d", i,j+1,idx);
			
			k++;
		}
	}
	
	// random blocks
	for(i=0; i<BLOCK_ROW_NUMBER; i++){	
		for(j=0; j< BLOCK_COL_NUMBER; j++){
			// get block
			int rj = arc4random() % (BLOCK_ROW_NUMBER - 1);
			int ri = arc4random() % (BLOCK_COL_NUMBER - 1);
			int tmp = blocks[i][j];
			blocks[i][j] = blocks[ri][rj];
			blocks[ri][rj] = tmp;
		}
	}
	
	
}

- (void)clearBlocks {
	// AtlasSpriteManager *mgr = (AtlasSpriteManager*) [self getChildByTag:kTagSpriteManager];
}

- (void)drawBlocks{
	int i,j;
	
	AtlasSpriteManager *mgr = (AtlasSpriteManager*) [self getChildByTag:kTagSpriteManager];
	// [mgr removeAllChildrenWithCleanup:TRUE];
	
	for(i=0; i< BLOCK_ROW_NUMBER; i++){
		for(j=0; j< BLOCK_COL_NUMBER; j++){
			
			// get block
			int idx = blocks[i][j];
			
			int x = (idx%5) * BLOCK_SIZE;
			// int yidx = CCRANDOM_0_1() * 400 / 100;
			int y = (idx/5) * BLOCK_SIZE;
			// void *btidx = &block_types + (sizeof(int))*idx;
			
			
			//NSLog(@"btidx: %p", btidx);
			
			AtlasSprite *sprite = [AtlasSprite spriteWithRect:CGRectMake(x,y,BLOCK_SIZE,BLOCK_SIZE) spriteManager:mgr];
			int ttag = i * 100 + j;
			[mgr addChild:sprite z:0 tag:ttag];
			sprite.position = ccp( i * BLOCK_SIZE + BLOCK_SIZE  , j * BLOCK_SIZE + BLOCK_SIZE );	
			
		}
	}
}

- (BOOL)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
	UITouch *touch = [touches anyObject];
	
	if( touch ) {
		CGPoint location = [touch locationInView: [touch view]];
		
		// IMPORTANT:
		// The touches are always in "portrait" coordinates. You need to convert them to your current orientation
		CGPoint convertedPoint = [[Director sharedDirector] convertToGL:location];
		
		// CocosNode *sprite = [self getChildByTag:kTagSprite];
		
		// we stop the all running actions
		// [sprite stopAllActions];
		
		// and we run a new action
		// [sprite runAction: [MoveTo actionWith:1 position:convertedPoint]];
		
		// [[Director sharedDirector] pushScene: [HelloWorld scene]];
		NSLog(@" x, y %f, %f ", convertedPoint.x, convertedPoint.y);
		
		int i,j;
		i = ( (int)(convertedPoint.x) - BLOCK_SIZE / 2 ) / BLOCK_SIZE;
		j = ( (int)(convertedPoint.y) - BLOCK_SIZE / 2 ) / BLOCK_SIZE;
		
		int v = blocks[i][j];
		
		NSLog(@" i, j %d, %d [ %d ] ", i, j, v);
		
		block_position bp;
		bp.i = i;
		bp.j = j;
		if([self haveSelectedBlock]){
			[self checkPair:bp];
		} else {
			
			[self selectBlock:bp];
		}
		
		
		// [(LevelScene *) [[[Director sharedDirector] runningScene] getChildByTag:kTagLevelLayer] clickBlockRow:i col:j];
		// [[[self parent] parent] clickBlockRow:i col:j];
		
		// no other handlers will receive this event
		return kEventHandled;
	}
	
	// we ignore the event. Other receivers will receive this event.
	return kEventIgnored;
}




- (void) selectBlock:(block_position)p {
	
	if(blocks[p.i][p.j] < 0){
		return;
	}
	
	selectedBlock = p;
	
	Sprite *bm = (Sprite *)[self getChildByTag:kBlockSpriteMask];
	bm.position = ccp( p.i * BLOCK_SIZE + BLOCK_SIZE  , p.j * BLOCK_SIZE + BLOCK_SIZE );	
	bm.visible = TRUE;
}

- (void) unselectBlock{
	selectedBlock.i = -1;
	selectedBlock.j = -1;
	
	// id actionBlink = [Blink actionWithDuration:2  position: ccp(80,80)];
	Sprite *bm = (Sprite *)[self getChildByTag:kBlockSpriteMask];
	// bm.position = ccp( i * BLOCK_SIZE + BLOCK_SIZE  , j * BLOCK_SIZE + BLOCK_SIZE );	
	bm.visible = FALSE;
}

- (void) checkPair:(block_position)p1{
	block_position p2 = selectedBlock;
	[self checkPair:p1 with:p2 testOnly:FALSE];
}

- (BOOL) checkPair:(block_position)p1 with:(block_position)p2 testOnly:(BOOL)test {
	
	
	NSLog(@"check pair (%d,%d) - (%d,%d)", p1.i, p1.j, p2.i, p2.j);
	
	if(!test){
		// check if 2 block
		if(p2.i == p1.i && p2.j == p1.j){
			// the same block, unsel
			[self unselectBlock];
			return FALSE;
		}
		
		if(blocks[p1.i][p1.j] != blocks[p2.i][p2.j] || blocks[p1.i][p1.j] < 0){
			// not same type
			[self unselectBlock];
			return FALSE;
		}
		
		if(p2.i < 0 || p2.j < 0){
			// invalid check block
			// not checked ?
			
			return FALSE;
		}
	}
	
	// 0 nearby
	NSLog(@"try 0");
	if(abs(p1.i - p2.i) + abs(p1.j - p2.j) == 1){
		// nearby
		NSLog(@"TYPE ZERO");
		if(!test){
			[self blockLineFrom:p1 to:p2];
			[self removePair:p1];
		}
		return TRUE;
	}
	
	
	// 1 line
	NSLog(@"try 1");
	if(p1.i == p2.i || p1.j == p2.j){
		if([self blockLineDirect:p1 to:p2]){
			NSLog(@"TYPE ONE");
			if(!test){
				[self blockLineFrom:p1 to:p2];
				[self removePair:p1];
			}
			return TRUE;
		}
		
	}
	
	// 2 line2
	NSLog(@"try 2");
	block_position cp1 = block_position_make(p1.i, p2.j);
	block_position cp2 = block_position_make(p2.i, p1.j);
	if(blocks[cp1.i][cp1.j] < 0 && [self blockLineDirect:p1 to:cp1] && [self blockLineDirect:cp1 to:p2]){
		NSLog(@"TYPE TWO 1 (%d,%d) - (%d,%d) - (%d,%d)", p1.i, p1.j, cp1.i, cp1.j, p2.i, p2.j);
		if(!test){
			[self blockLineFrom:p1 to:cp1];
			[self blockLineFrom:cp1 to:p2];
			[self removePair:p1];
		}
		return TRUE;
	} else if(blocks[cp2.i][cp2.j] < 0 && [self blockLineDirect:p1 to:cp2] && [self blockLineDirect:cp2 to:p2]){
		NSLog(@"TYPE TWO 2 (%d,%d) - (%d,%d) - (%d,%d)", p1.i, p1.j, cp2.i, cp2.j, p2.i, p2.j);
		if(!test){
			[self blockLineFrom:p1 to:cp2];
			[self blockLineFrom:cp2 to:p2];
			[self removePair:p1];
		}
		return TRUE;
	} else if(blocks[cp1.i][cp1.j] >= 0){
		NSLog(@"block exists (%d,%d) %d", cp1.i, cp1.j, blocks[cp1.i][cp1.j]);
	} else if(blocks[cp2.i][cp2.j] >= 0){
		NSLog(@"block exists (%d,%d) %d", cp2.i, cp2.j, blocks[cp2.i][cp2.j]);
	}
	
	
	
	
	// 3 line2
	NSLog(@"try 3");
	int cc;
	
	// check in U and n
	for(cc = -1; cc < BLOCK_COL_NUMBER + 1 ; cc++){
		if( cc == p1.j || cc == p2.j ){
			continue;
		}
		
		block_position cp1 = block_position_make(p1.i, cc);
		block_position cp2 = block_position_make(p2.i, cc);
		NSLog(@"3.1 (%d,%d) - (%d,%d) - (%d,%d) - (%d,%d)", p1.i, p1.j, cp1.i, cp1.j, cp2.i, cp2.j, p2.i, p2.j);
		
		if(cc > -1 && cc < BLOCK_COL_NUMBER){
			// check cp1, cp2
			if(blocks[cp1.i][cp1.j] > -1 || blocks[cp2.i][cp2.j] > -1){
				continue;
			}
		}
		
		if([self blockLineDirect:p1 to:cp1] && [self blockLineDirect:cp1 to:cp2] && [self blockLineDirect:cp2 to:p2]){
			NSLog(@"TYPE THREE 1");
			if(!test){
				[self blockLineFrom:p1 to:cp1];
				[self blockLineFrom:cp1 to:cp2];
				[self blockLineFrom:cp2 to:p2];
				[self removePair:p1];
			}
			return TRUE;
		}
	}
	
	// check in [ or ]
	for(cc = -1; cc < BLOCK_ROW_NUMBER + 1 ; cc++){
		if( cc == p1.i || cc == p2.i ){
			continue;
		}
		
		block_position cp1 = block_position_make(cc, p1.j);
		block_position cp2 = block_position_make(cc, p2.j);
		NSLog(@"3.2 (%d,%d) - (%d,%d) - (%d,%d) - (%d,%d)", p1.i, p1.j, cp1.i, cp1.j, cp2.i, cp2.j, p2.i, p2.j);
		
		if(cc > -1 && cc < BLOCK_ROW_NUMBER){
			// check cp1, cp2
			if(blocks[cp1.i][cp1.j] > -1 || blocks[cp2.i][cp2.j] > -1){
				continue;
			}
		}
		
		if([self blockLineDirect:p1 to:cp1] && [self blockLineDirect:cp1 to:cp2] && [self blockLineDirect:cp2 to:p2]){
			NSLog(@"TYPE THREE 2");
			if(!test){
				[self blockLineFrom:p1 to:cp1];
				[self blockLineFrom:cp1 to:cp2];
				[self blockLineFrom:cp2 to:p2];
				[self removePair:p1];
			}
			
			return TRUE;
		}
	}
	
	// all failed.
	if(!test){
		[self unselectBlock];
	}
	
	return FALSE;
}

- (void) removePair:(block_position)p1{
	
	anotherBlock = p1;
	
	[self runAction: [Sequence actions:[DelayTime actionWithDuration: 0.1], [CallFunc actionWithTarget:self selector:@selector(doRemovePair)], nil]];
	
	// block_left_number = block_left_number - 2;
	// NSLog(@"left blocks: %d", block_left_number);
	
	
}

- (void) doRemovePair{
	NSLog(@"remove pair");
	block_position p1 = anotherBlock;
	block_position p2 = selectedBlock;
	
	AtlasSpriteManager *mgr = (AtlasSpriteManager*) [self getChildByTag:kTagSpriteManager];
	
	int ttag = p1.i * 100 + p1.j;
	[mgr removeChildByTag:ttag cleanup:TRUE];
	// AtlasSprite *sp1 = (AtlasSprite *)[mgr getChildByTag:ttag];
	// sp1.visible = FALSE;
	
	int ttag2 = p2.i * 100 + p2.j;
	[mgr removeChildByTag:ttag2 cleanup:TRUE];
	// AtlasSprite *sp2 = (AtlasSprite *)[mgr getChildByTag:ttag2];
	// sp2.visible = FALSE;
	
	
	blocks[p1.i][p1.j] = -1;
	blocks[p2.i][p2.j] = -1;
	
	[self blockLineClear];
	
	[self unselectBlock];
	
	// do shift
	[self shiftBlocks:p1 and:p2];
	
	
	BOOL cleared = TRUE;
	int i, j;
	for(i = 0; i < BLOCK_ROW_NUMBER && cleared; i++){
		for(j = 0; j < BLOCK_COL_NUMBER && cleared; j++){
			if(blocks[i][j] >= 0){
				cleared = FALSE;
			}
		}
	}
	if(cleared){
		// level clear.
		[self levelClear];
	} else {
		// check if can be solved ?
		[self runAction: [Sequence actions:[DelayTime actionWithDuration: 1], [CallFunc actionWithTarget:self selector:@selector(testNextPair)], nil]];
	}
	
}

- (void) shiftBlocks:(block_position)p1 and:(block_position)p2 {
	NSLog(@"shift blocks");
	
	int i, j, k;
	AtlasSpriteManager *mgr = (AtlasSpriteManager*) [self getChildByTag:kTagSpriteManager];
	
	if(block_shift_direction == BLOCK_SHIFT_LEFT){
		NSLog(@"shift left <----");
		
		for(k=0; k<2; k++){
			for(i = 0; i < BLOCK_ROW_NUMBER - 1; i++){
				for(j = 0; j < BLOCK_COL_NUMBER; j++){
					
					if(blocks[i][j] < 0 && blocks[i+1][j] >= 0){
						blocks[i][j] = blocks[i+1][j];
						blocks[i+1][j] = -1;
						NSLog(@"shift (%d,%d) <- (%d,%d)", i, j, i+1, j);
						
						int ttag = ( i + 1 ) * 100 + j;
						int ttag2 = i * 100 + j;
						
						AtlasSprite *blk = (AtlasSprite *)[mgr getChildByTag:ttag];
						blk.tag = ttag2;
						
						CGPoint p = blk.position;
						blk.position = ccp(p.x - 32.0, p.y);
					}
				}
			}
		}
		
	} else if(block_shift_direction == BLOCK_SHIFT_RIGHT){
		NSLog(@"shift right ---->");
		
		for(k=0; k<2; k++){
			for(i = BLOCK_ROW_NUMBER - 1; i > 0; i--){
				for(j = 0; j < BLOCK_COL_NUMBER; j++){
					
					if(blocks[i][j] < 0 && blocks[i-1][j] >= 0){
						blocks[i][j] = blocks[i-1][j];
						blocks[i-1][j] = -1;
						NSLog(@"shift (%d,%d) <- (%d,%d)", i, j, i-1, j);
						
						int ttag = ( i - 1 ) * 100 + j;
						int ttag2 = i * 100 + j;
						
						AtlasSprite *blk = (AtlasSprite *)[mgr getChildByTag:ttag];
						CGPoint p = blk.position;
						blk.tag = ttag2;
						blk.position = ccp(p.x + 32.0, p.y);
					}
				}
			}
		}
	} else if(block_shift_direction == BLOCK_SHIFT_TOP){
		NSLog(@"shift top");
		
		for(k=0; k<2; k++){
			for(j = BLOCK_COL_NUMBER - 1; j > 0; j--){
				for(i = 0; i < BLOCK_ROW_NUMBER; i++){
					
					
					if(blocks[i][j] < 0 && blocks[i][j-1] >= 0){
						blocks[i][j] = blocks[i][j-1];
						blocks[i][j-1] = -1;
						NSLog(@"shift (%d,%d) <- (%d,%d)", i, j, i, j-1);
						
						int ttag = i * 100 + j - 1;
						int ttag2 = i * 100 + j;
						
						AtlasSprite *blk = (AtlasSprite *)[mgr getChildByTag:ttag];
						CGPoint p = blk.position;
						blk.tag = ttag2;
						blk.position = ccp(p.x , p.y + 32);
					}
				}
			}
		}
	} else if(block_shift_direction == BLOCK_SHIFT_BOTTOM){
		NSLog(@"shift bottom");
		
		for(k=0; k<2; k++){
			for(j = 0; j < BLOCK_COL_NUMBER - 1; j++){
				for(i = 0; i < BLOCK_ROW_NUMBER; i++){
					
					
					if(blocks[i][j] < 0 && blocks[i][j+1] >= 0){
						blocks[i][j] = blocks[i][j+1];
						blocks[i][j+1] = -1;
						NSLog(@"shift (%d,%d) <- (%d,%d)", i, j, i, j+1);
						
						int ttag = i * 100 + j + 1;
						int ttag2 = i * 100 + j;
						
						AtlasSprite *blk = (AtlasSprite *)[mgr getChildByTag:ttag];
						CGPoint p = blk.position;
						blk.tag = ttag2;
						blk.position = ccp(p.x , p.y - 32);
					}
				}
			}
		}
	}
	
}

- (BOOL)haveSelectedBlock {
	if(selectedBlock.i > -1 && selectedBlock.j > -1){
		return TRUE;
	} else {
		return FALSE;
	}
}

/**
 * check if two block can see each other directly
 * XXX: NOT checking if p1 and p2 are OK.
 */
- (BOOL) blockLineDirect:(block_position)p1 to:(block_position)p2{
	NSLog(@"direct checking (%d,%d) - (%d,%d)", p1.i, p1.j, p2.i, p2.j);
	
	if(p1.i == p2.i){
		if(p1.i < 0 || p1.i >= BLOCK_ROW_NUMBER){
			// checking in boundary, ok
			NSLog(@"direct checking boundary");
			return TRUE;
		}
		
		int from = MIN(p1.j, p2.j);
		int to = MAX(p1.j, p2.j);
		if(to - from == 1){
			NSLog(@"direct checking nearby");
			return TRUE;
		}
		
		int k;
		for(k=from+1; k<to; k++){
			if(blocks[p1.i][k] > -1){
				NSLog(@"direct checking have block (%d, %d) %d", p1.i, k, blocks[p1.i][k] );
				return FALSE;
			}
		}
		NSLog(@"direct checking ok");
		return TRUE;
	} else if(p1.j == p2.j){
		if(p1.j < 0 || p1.j >= BLOCK_COL_NUMBER){
			// checking in boundary, ok
			NSLog(@"direct checking boundary");
			return TRUE;
		}
		
		int from = MIN(p1.i, p2.i);
		int to = MAX(p1.i, p2.i);
		if(to - from == 1){
			NSLog(@"direct checking nearby");
			return TRUE;
		}
		
		int k;
		for(k=from+1; k<to; k++){
			if(blocks[k][p1.j] > -1){
				NSLog(@"direct checking have block (%d, %d)", k, p1.j, blocks[k][p1.j]);
				return FALSE;
			}
		}
		NSLog(@"direct checking ok");
		return TRUE;
	} else {
		NSLog(@"direct checking not in line.");
		return FALSE;
	}
}

- (void) blockLineFrom:(block_position)p1 to:(block_position)p2 {
	// glColor4f(0.8, 1.0, 0.76, 1.0);  
	// glLineWidth(2.0f);
	
	CGPoint fp = CGPointMake(p1.i * BLOCK_SIZE + BLOCK_SIZE, p1.j * BLOCK_SIZE + BLOCK_SIZE);
	CGPoint tp = CGPointMake(p2.i * BLOCK_SIZE + BLOCK_SIZE, p2.j * BLOCK_SIZE + BLOCK_SIZE);
	
	// CocosNode *line = drawLine(fp, tp);
	// [self addChild:line z:1];
	
	// add tick to clear line
	
	
	
	block_line_path blp;
	blp.from = fp;
	blp.to = tp;
	
	
	LineLayer *ll = (LineLayer *) [self getChildByTag:kLineLayer];
	[ll addLine:blp];
	
	
}

- (void) blockLineClear{
	LineLayer *ll = (LineLayer *) [self getChildByTag:kLineLayer];
	[ll clearPath];
}


- (void) timesUp {
	
}

- (void) levelClear {
	TimerBarLayer *tbl = (TimerBarLayer *) [self getChildByTag:kTagTimerBarLayer];
	[tbl stopTimer];
	
	int level = [[GameData sharedObject] getLevel];
	int next_level = level + 1;
	NSLog(@"next level %d", next_level);
	[[GameData sharedObject] setLevel:next_level];
	
	if(next_level > 10){
		// game over
		[[Director sharedDirector] replaceScene: [ShrinkGrowTransition transitionWithDuration:0.5 scene:[LevelScene scene] ]];
	} else {
		// next level
		[[Director sharedDirector] replaceScene: [FlipAngularTransition transitionWithDuration:0.5 scene:[LevelScene scene] ]];
	}
}


/** test if have next pair
 * if no pair, switch random pair and test again
 */

- (BOOL) testNextPairOnce {
	
	int i, j, k;
	
	BOOL found_pair = FALSE;
	for(k = 0; k < block_type_number && !found_pair; k++){
		block_position bps[100]; // COL * ROW + 1 is OK
		int bps_idx = 0;
		
		for(i = 0; i < BLOCK_ROW_NUMBER; i++){
			for(j = 0; j < BLOCK_COL_NUMBER; j++){
				if(blocks[i][j] == k){
					bps[bps_idx] = block_position_make(i, j);
					bps_idx++;
				}
			}
		}
		
		if(bps_idx == 0){
			continue;
		}
		
		
		for(i = 0; i< bps_idx && !found_pair; i++){
			for(j = i + 1; j < bps_idx && !found_pair; j++){
				block_position bp1 = bps[i];
				block_position bp2 = bps[j];
				
				if([self checkPair:bp1 with:bp2 testOnly:TRUE]){
					found_pair = TRUE;
				}
				
			}
		}
	}
	
	return found_pair;

}

- (void) testNextPair {

	return;
	
	BOOL found_pair;
	do {
		
		found_pair = [self testNextPairOnce];
		NSLog(@"check pair %d", found_pair);
		
		if(!found_pair){
			
			int i,j;
			
			block_position bps[100]; // COL * ROW + 1 is OK
			int bps_idx = 0;
			
			for(i = 0; i < BLOCK_ROW_NUMBER; i++){
				for(j = 0; j < BLOCK_COL_NUMBER; j++){
					if(blocks[i][j] >= 0){
						bps[bps_idx] = block_position_make(i, j);
						bps_idx++;
					}
				}
			}
			
			NSAssert(bps_idx > 0, @"no blocks but still finding pair.");
			
			int idx1 = arc4random() % bps_idx;
			int idx2 = arc4random() % bps_idx;
			
			block_position bp1 = bps[idx1];
			block_position bp2 = bps[idx2];
			
			int ttag1 = bp1.i * 100 + bp1.j;
			int ttag2 = bp2.i * 100 + bp2.j;
			
			
			// switch bp1 and bp2			
			int tmp = blocks[bp1.i][bp1.j];
			blocks[bp1.i][bp1.j] = blocks[bp2.i][bp2.j];
			blocks[bp2.i][bp2.j] = tmp;
			
			// switch sprite
			AtlasSpriteManager *mgr = (AtlasSpriteManager*) [self getChildByTag:kTagSpriteManager];
			
			AtlasSprite *blk1 = (AtlasSprite *)[mgr getChildByTag:ttag1];
			AtlasSprite *blk2 = (AtlasSprite *)[mgr getChildByTag:ttag2];
			CGPoint p1 = blk1.position;
			CGPoint p2 = blk2.position;
			
			blk1.tag = ttag2;
			blk1.position = p2;
			
			blk2.tag = ttag1;
			blk2.position = p1;
			
		}
		
	} while(!found_pair);
	
		// do switch and check again
		
		

}


// on "dealloc" you need to release all your retained objects
- (void) dealloc
{
	// in case you have something to dealloc, do it in this method
	// in this particular example nothing needs to be released.
	// cocos2d will automatically release all the children (Label)
	[ta release];
	
	// don't forget to call "super dealloc"
	[super dealloc];
}


@end
